import os
import time
import threading
import queue
import logging
import json

from config import UPLOAD_FOLDER, SPEECHEMO_FOLDER
from minio_manager import minio_manager
from audio_processor import process_audio
from asr_manager import process_audio_speech_emotion
from database import save_session_to_database, update_sound_record_status,save_session_score
from llm_manager import LLMManager
from score_card import ScoreCard 

logger = logging.getLogger('async_processor')

_job_queue: "queue.Queue[dict]" = queue.Queue(maxsize=1000)
_worker_thread = None
_stop_event = threading.Event()

# 初始化LLM管理器实例
llm_manager = LLMManager()

def start_worker():
    global _worker_thread
    if _worker_thread and _worker_thread.is_alive():
        return
    _worker_thread = threading.Thread(target=_worker_loop, name="async-audio-worker", daemon=True)
    _worker_thread.start()
    logger.info("异步处理工作线程已启动")


def enqueue_job(job: dict):
    """入队任务。job需要包含: device_no, base_file_name, chunk_index, minio_url, time_pairs."""
    _job_queue.put(job)
    logger.info(f"任务已入队: {job.get('device_no')} {job.get('base_file_name')} #{job.get('chunk_index')}")


def _worker_loop():
    while not _stop_event.is_set():
        try:
            job = _job_queue.get(timeout=1)
        except queue.Empty:
            continue

        device_no = job.get('device_no')
        base_file_name = job.get('base_file_name')
        chunk_index = job.get('chunk_index')
        minio_url = job.get('minio_url')
        time_pairs = job.get('time_pairs') or []

        try:
            # 标记状态：分析中(2)
            update_sound_record_status(device_no, base_file_name, chunk_index, '2')

            # 下载音频到本地临时文件
            object_name = minio_url.split('/')[-1]
            temp_path = os.path.join(UPLOAD_FOLDER, f"{base_file_name}")
            minio_manager.client.fget_object(minio_manager.bucket_name, object_name, temp_path)

            processed_files = None
            if time_pairs:
                processed_files = process_audio(temp_path, time_pairs)

            # 逐条入库会话，并将处理后的片段上传到MinIO
            if processed_files:
                for item in processed_files:
                    if isinstance(item, dict):
                        file_path = item["file_path"]
                        is_cross_file = item["is_cross_file"]
                        original_files = item["original_files"]
                        in_time = item["in_time"]
                        out_time = item["out_time"]
                        # 生成会话编号 session_no（设备+时间）
                        session_no = f"{device_no}_{in_time}"
                        
                        # 先进行语音识别（在删除文件之前）
                        segment_base_name = os.path.splitext(os.path.basename(file_path))[0]
                        output_txt_path = os.path.join(SPEECHEMO_FOLDER, f"{segment_base_name}.txt")
                        text_content = None
                        try:
                            if os.path.exists(file_path):
                                if process_audio_speech_emotion(file_path, output_txt_path) and os.path.exists(output_txt_path):
                                    with open(output_txt_path, 'r', encoding='utf-8') as f:
                                        text_content = f.read()
                        except Exception as e:
                            logger.warning(f"情绪转写失败: {e}")
                        
                        # 上传片段到MinIO（在语音识别之后）
                        processed_url = None
                        if os.path.exists(file_path):
                            processed_url = minio_manager.upload_file(file_path)
                            try:
                                os.remove(file_path)
                            except Exception:
                                pass

                        # 调用LLM处理文本内容
                        llm_result  = None
                        session_desc = "无有效业务信息"  # 默认值
                        key_events_str = None  # 新增：用于存储key_events

                        if text_content:
                            session_desc='待AI分析总结'
                            key_events='待AI分析总结'
                        else:
                            session_desc = "无有效业务信息"
                            key_events=''

             
                        saved = save_session_to_database(
                            session_no=session_no,
                            device_no=device_no,
                            original_files=",".join(original_files) if isinstance(original_files, list) else str(original_files),
                            session_file=processed_url,
                            in_time=in_time,
                            out_time=out_time,
                            is_cross_file=is_cross_file,
                            conversation_text=text_content,
                            session_desc=session_desc,
                            key_events=key_events
                        )

                        if not saved:
                            logger.info(f"会话未保存（文本为空或时长不足60s）: {session_no}")
                        
                        # 评分卡流程（qa_score_result/details/report）
                        if saved:
                            try:
                                # 初始化评分卡（假设规则路径已配置）
                                score_card = ScoreCard(rule_path="rule_config.yaml")
                                # 将评分结果存入数据库
                                score_card.process_and_save(
                                    session_no=session_no,
                                    conversation_text=text_content,
                                    file_path=output_txt_path
                                )
                                logger.info(f"会话[{session_no}]评分卡流程已完成（qa_score_result/details/report）")
                            except Exception as e:
                                logger.warning(f"评分卡流程失败: {e}")
                    else:
                        # 旧格式字符串
                        file_basename = os.path.basename(item)
                        processed_url = None
                        if os.path.exists(item):
                            processed_url = minio_manager.upload_file(item)
                            try:
                                os.remove(item)
                            except Exception:
                                pass
                        parts = file_basename.split('_')
                        if len(parts) >= 5:
                            in_time = parts[-2]
                            out_time = parts[-1].replace('.mp3', '')
                            saved = save_session_to_database(
                                session_no=session_no,
                                device_no=device_no,
                                original_files=base_file_name,
                                session_file=processed_url,
                                in_time=in_time,
                                out_time=out_time,
                                is_cross_file=False
                            )

                            if not saved:
                                logger.info(f"会话未保存（文本为空或时长不足60s）: {session_no}")

            # 状态：分析完成(3)
            update_sound_record_status(device_no, base_file_name, chunk_index, '3')

        except Exception as e:
            logger.error(f"异步处理失败: {str(e)}", exc_info=True)
            # 状态：无效音频(4)
            try:
                update_sound_record_status(device_no, base_file_name, chunk_index, '4')
            except Exception:
                pass
        finally:
            # 清理下载的源文件
            try:
                if os.path.exists(temp_path):
                    os.remove(temp_path)
            except Exception:
                pass
            _job_queue.task_done()




